package com.offcn.pay.controller;

import com.alibaba.fastjson2.JSON;
import com.offcn.common.entity.Result;
import com.offcn.common.entity.StatusCode;
import com.offcn.common.utils.IdWorker;
import com.offcn.order.feign.OrderFeign;
import com.offcn.order.pojo.PayLog;
import com.offcn.pay.servicer.AliPayService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付控制器
 *
 * @author 秋林
 * @date 2022/10/17 20:38:15
 */
@RestController
@RequestMapping("/pay")
public class PayController {
    @Autowired
    private AliPayService aliPayService;

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 生成二维码[方案一]
     *
     * @return {@link Map}
     */
    @GetMapping("/createNative")
    public Map createNative() {
        Result<PayLog> payLogResult = orderFeign.searchPayLogFromRedis();
        PayLog payLog = payLogResult.getData();
        if (!StringUtils.isEmpty(payLog)) {
            return aliPayService.createNative(payLog.getOutTradeNo(), payLog.getTotalFee() + "");
        } else {
            return new HashMap();
        }
    }

    /**
     * 查询支付状态
     *
     * @param out_trade_no 支付时传入的商户订单号
     * @return {@link Result}
     */
    @RequestMapping("/queryPayStatus")
    public Result queryPayStatus(String out_trade_no) {
        Result result = null;

        int x = 0;

        while (true) {
            //调用查询接口
            Map<String, String> map = null;
            try {
                map = aliPayService.queryPayStatus(out_trade_no);
            } catch (Exception e) {
                System.out.println("调用查询服务出错");
            }

            //出错
            if (map == null) {
                result = new Result(false, StatusCode.ERROR, "支付出错");
                System.out.println("支付出错");
                break;
            }

            //如果成功
            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_SUCCESS")) {
                result = new Result(false, StatusCode.OK, "支付成功");
                orderFeign.updateOrderStatus(map.get("out_trade_no"), map.get("trade_no"));
                System.out.println("支付成功");
                break;
            }

            //如果成功
            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_CLOSED")) {
                result = new Result(true, StatusCode.OK, "未付款交易超时关闭，或支付完成后全额退款");
                System.out.println("未付款交易超时关闭，或支付完成后全额退款");
                break;
            }

            //如果成功
            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_FINISHED")) {
                result = new Result(true, StatusCode.OK, "交易结束，不可退款");
                System.out.println("交易结束，不可退款");
                break;
            }

            try {
                //间隔3秒
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            x++;
            if (x >= 100) {
                result = new Result(false, StatusCode.ERROR, "二维码超时");
                System.out.println("二维码超时");
                break;
            }
        }
        return result;
    }

    @RequestMapping("/create/native")
    public Result<Map> createNative(@RequestParam Map<String, String> parameters){
        //获取用户名
        Map resultMap = aliPayService.createNative(parameters);

        return new Result<Map>(true,StatusCode.OK,"二维码创建成功",resultMap);
    }

    /**
     * 接收 支付通知的结果
     * 方法的核心操作是远程调用到秒杀模块做后续处理(修改订单状态/回滚库存等)
     * 调用秒杀模块可选择Feign远程调用 或 RabbitMQ消息通知, 因为超时未付款选择了延迟消息队列(死循环累加技术太耗费性能)
     * 所以支付状态的通知也选择消息队列通知
     *
     * @param request 请求
     * @return {@link String}
     */
    @RequestMapping("/notify/url")
    public String notifyResult(HttpServletRequest request){
        HashMap<String, String> map = new HashMap<>();

        Enumeration attributeNames = request.getParameterNames();
        while (attributeNames.hasMoreElements()){
            Object element = attributeNames.nextElement();
            String attributeName = element.toString();
            map.put(attributeName,request.getParameter(attributeName));
        }

        String jsonString = JSON.toJSONString(map);
        System.out.println("rabbitmq消息:"+jsonString);

        String body = map.get("body");

        String[] splits = body.split("&");

        HashMap<String, String> bodyMap = new HashMap<>();
        for (String split : splits) {
            String[] vs = split.split("=");
            bodyMap.put(vs[0],vs[1]);
        }

        /*
         *方法的核心操作是远程调用到秒杀模块做后续处理(修改订单状态/回滚库存等)
         *调用秒杀模块可选择Feign远程调用 或 RabbitMQ消息通知, 因为超时未付款选择了延迟消息队列(死循环累加技术太耗费性能)
       	 *所以支付状态的通知也选择消息队列通知
         */
        rabbitTemplate.convertAndSend(bodyMap.get("exchange"),bodyMap.get("routingkey"),jsonString);

        return "支付成功";
    }
}
